using CfgTable;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using System.Collections.Generic;

namespace IQIGame.Onigao.GamePlay
{
    public class UIWarehouse : UIBaseWindow
    {
        /// <summary>
        /// 静态配置
        /// </summary>
        private static UICreateConfig _createConfig = new()
        {
            prefabName = nameof(UIWarehouse),
            layer = EUILayer.Normal,
        };

        /// <summary>
        /// 创建UI的配置
        /// </summary>
        public override IUICreateConfig createConfig => _createConfig;

        #region Template Generate,don't modify
        protected partial class UIB_UIWarehouse
        {
            #region ObjectBinding Generate
            public UnityEngine.GameObject tag { protected set; get; }
            public UnityEngine.UI.ExLoopVerticalScrollRect loopVerticalScrollRect { protected set; get; }
            public UnityEngine.GameObject moneyPanel { protected set; get; }
            public UnityEngine.GameObject empty { protected set; get; }
            public UnityEngine.GameObject itemTipsPanel { protected set; get; }
            public UnityEngine.GameObject topLeftBack { protected set; get; }
            public virtual void InitBinding(ObjectBinding __binding)
            {
                __binding.TryGetVariableValue<UnityEngine.GameObject>("tag", out var __tbv0);
                this.tag = __tbv0;
                __binding.TryGetVariableValue<UnityEngine.UI.ExLoopVerticalScrollRect>("loopVerticalScrollRect", out var __tbv1);
                this.loopVerticalScrollRect = __tbv1;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("moneyPanel", out var __tbv2);
                this.moneyPanel = __tbv2;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("empty", out var __tbv3);
                this.empty = __tbv3;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("itemTipsPanel", out var __tbv4);
                this.itemTipsPanel = __tbv4;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("topLeftBack", out var __tbv5);
                this.topLeftBack = __tbv5;
            }
            #endregion ObjectBinding Generate 
        }
        #endregion Template Generate,don't modify

        #region fields & properties
        private ListScrollAdapter<UIN_WarehouseTab> tabs = null;
        private LoopScrollAdapter<UIN_WarehouseItem> itemCells = null;
        private UIN_MoneyPanel topMoney = null;
        private UIN_CommonItemTips itemTip = null;

        private int indexSelectedTab = -1;
        private List<ItemData> dataList = new(8);
        private Dictionary<int, int> dicTabItemSelected = new(2);

        protected UIB_UIWarehouse ui { get; set; }
        private UIMsgDispatcher currMsgDispatcher => this._msgDispatcher as UIMsgDispatcher;
        #endregion

        protected override void BeforeInit()
        {
            ui = new UIB_UIWarehouse();
            ui.InitBinding(this.csObjBind);
        }

        protected override void OnInit()
        {
            this.ui.empty.SetActive(false);

            this.topMoney = this.InitChildNode<UIN_MoneyPanel>(this.ui.moneyPanel);
            this.topMoney.Show(nameof(UIWarehouse));

            this.itemTip = this.InitChildNode<UIN_CommonItemTips>(this.ui.itemTipsPanel);

            this.tabs = this.InitListScroll<UIN_WarehouseTab>(this.ui.tag, this.OnTabChanged);
            this.tabs.InitUnitSelected(UnitSelectType.ByExToggle, this.OnTabSelected);
            this.itemCells = this.InitLoopScroll<UIN_WarehouseItem>(this.ui.loopVerticalScrollRect, this.OnItemChanged);
            this.itemCells.InitUnitSelected(UnitSelectType.ByExButton, this.OnItemSelected);

            var topLeftBack = this.InitChildNode<UIN_TopLeftBack>(this.ui.topLeftBack);
            topLeftBack.Show();
        }

        protected override void OnShow(UIBaseData data)
        {
            int cnt = (int)UIWarehouseTabType.MaxLength;
            this.tabs.RefillCells(cnt, 0);
        }

        protected override void OnHide()
        {

        }

        protected override void AddMsgListeners()
        {
            currMsgDispatcher.AddListener(MsgEventType.ItemChanged, this.OnMsgItemChanged);
        }

        protected override void OnDispose()
        {
            this.ClearDataList();
        }

        private void OnTabChanged(UIN_WarehouseTab tab, int index)
        {
            this.dicTabItemSelected.TryGetValue(index, out var indexItem);
            this.dicTabItemSelected[index] = indexItem;
            tab.Show(index);
        }

        private void OnTabSelected(int index, UIN_WarehouseTab tab)
        {
            this.indexSelectedTab = index;
            this.ViewRightItem();
        }

        private void ViewRightItem()
        {
            this.InitDataList();
            int cnt = this.dataList.Count;
            if (!this.dicTabItemSelected.TryGetValue(this.indexSelectedTab, out var _itemIndex))
                _itemIndex = 0;
            this.itemCells.RefillCellsAndSelected(cnt, _itemIndex);
        }

        private void ClearDataList()
        {
            this.dataList.Clear();
        }

        private void InitDataList()
        {
            this.ClearDataList();
            var funcAdd = MakeSortFunc(this.indexSelectedTab);
            var moduleData = GameDataCenter.PlayerData.item;
            var list = moduleData.GetSortItemList(funcAdd, this.SortDataList);
            this.dataList.AddRange(list);
        }

        private System.Func<ItemData, bool> MakeSortFunc(int tabIndex)
        {
            return itemData =>
            {
                if (itemData.num > 0)
                {
                    CfgItem cfg = itemData.cfgData;
                    if (cfg != null && cfg.IsBagShow && cfg.Tab > 0 && (tabIndex == 0 || cfg.Tab == tabIndex))
                    {
                        return true;
                    }
                }
                return false;
            };
        }

        private int SortDataList(ItemData a, ItemData b)
        {
            var cfgA = a.cfgData;
            var cfgB = b.cfgData;
            if (cfgA.Sort != cfgB.Sort)
                return cfgA.Sort > cfgB.Sort ? -1 : 1;
            return a.id > b.id ? -1 : 1;
        }

        private void OnItemChanged(UIN_WarehouseItem item, int index)
        {
            var svData = this.dataList[index];
            item.Show(svData);
            bool isSelected = this.itemCells.selectedIndex == index;
            item.SetSelected(isSelected);
        }

        private void OnItemSelected(int index, UIN_WarehouseItem item)
        {
            if (this.dicTabItemSelected.TryGetValue(this.indexSelectedTab, out int lastIndex))
            {
                var itemLast = this.itemCells.GetTEntity(lastIndex);
                itemLast?.SetSelected(false);
            }
            item?.SetSelected(true);
            this.dicTabItemSelected[this.indexSelectedTab] = index;
            ItemData itemData = item != null ? this.dataList[index] : null;
            this.ViewItemTip(itemData);
        }

        private void ViewItemTip(ItemData itemData)
        {
            this.itemTip.Show(itemData);
            bool isActiveEmpty = (itemData == null) || (itemData.cfgData == null);
            this.ui.empty.SetActive(isActiveEmpty);
        }

        private void OnMsgItemChanged()
        {
            this.ViewRightItem();
        }
    }
}
